package org.kepler.chat.api.config;

import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.kepler.chat.api.infra.util.Des;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;

import javax.sql.DataSource;
import java.sql.SQLException;

@Configuration
// @PropertySource({"classpath:/application.yml"})
// 启用注解事务管理，使用CGLib代理
// @EnableTransactionManagement(proxyTargetClass = true)
// @EnableJpaRepositories(basePackages = "com.at.mul.repository.customer",
// entityManagerFactoryRef = "customerEntityManager", transactionManagerRef = "transactionManager")
public class DataSourceConfig {

	String strKey = "1002000100010002";

	@Value("${encrypt}")
	boolean encrypt;

	@Value("${initialSize:10}")
	int initialSize;
	@Value("${maxActive}")
	int maxActive;
	@Value("${minIdle}")
	int minIdle;
	@Value("${validationQuery}")
	String validationQuery;
	@Value("${removeAbandoned}")
	boolean removeAbandoned;
	@Value("${removeAbandonedTimeout}")
	int removeAbandonedTimeout;

	@Value("${loan.jdbc.driver}")
	String loan_driverClass;
	String loan_jdbc_url;
	String loan_jdbc_username;
	String loan_jdbc_password;


	@Value("${loan.jdbc.url}")
	public void setLoan_jdbc_url(String loan_jdbc_url) {
		if(encrypt) {
			this.loan_jdbc_url = Des.Decrypt(loan_jdbc_url, Des.hex2byte(strKey));
		}else{
			this.loan_jdbc_url = loan_jdbc_url;
		}
	}

	@Value("${loan.jdbc.username}")
	public void setLoan_jdbc_username(String loan_jdbc_username) {
		if(encrypt) {
			this.loan_jdbc_username = Des.Decrypt(loan_jdbc_username, Des.hex2byte(strKey));
		}else{
			this.loan_jdbc_username = loan_jdbc_username;
		}
	}

	@Value("${loan.jdbc.password}")
	public void setLoan_jdbc_password(String loan_jdbc_password) {
		if(encrypt) {
			this.loan_jdbc_password = Des.Decrypt(loan_jdbc_password, Des.hex2byte(strKey));
		}else{
			this.loan_jdbc_password = loan_jdbc_password;
		}
	}

    @Primary
	@Bean(name = "atomikosDS_loan", initMethod = "init", destroyMethod = "close")
	public DataSource ds_loan() {
		DruidXADataSource druidXADataSource = new DruidXADataSource();
		druidXADataSource.setUrl(loan_jdbc_url);
		druidXADataSource.setUsername(loan_jdbc_username);
		druidXADataSource.setPassword(loan_jdbc_password);
		// 初始化连接大小
		druidXADataSource.setInitialSize(initialSize);
		// 连接池最大使用连接数量
		druidXADataSource.setMaxActive(maxActive);
		// 连接池最小空闲
		druidXADataSource.setMinIdle(minIdle);
		// 获取连接最大等待时间
		druidXADataSource.setMaxWait(60000);
		druidXADataSource.setPoolPreparedStatements(true);
		druidXADataSource.setMaxPoolPreparedStatementPerConnectionSize(33);
		druidXADataSource.setValidationQuery(validationQuery);
		druidXADataSource.setTestOnBorrow(false);
		druidXADataSource.setTestOnReturn(false);
		druidXADataSource.setTestWhileIdle(true);
		// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		druidXADataSource.setTimeBetweenEvictionRunsMillis(60000);
		// 配置一个连接在池中最小生存的时间，单位是毫秒
		druidXADataSource.setMinEvictableIdleTimeMillis(25200000);
		// 设置removeAbandoned功能
		druidXADataSource.setRemoveAbandoned(removeAbandoned);
		druidXADataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);
		druidXADataSource.setLogAbandoned(true);
		try {
			// 开启druid监控支持(stat)，SQL防火墙(wall)以及SQL合并(mergeStat)
			druidXADataSource.setFilters("stat,config");
		} catch (SQLException e) {
		}

		AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
		xaDataSource.setXaDataSource(druidXADataSource);
		xaDataSource.setUniqueResourceName("ds_loan");
		xaDataSource.setMinPoolSize(minIdle);
		xaDataSource.setMaxPoolSize(maxActive);
		xaDataSource.setReapTimeout(60);
		xaDataSource.setBorrowConnectionTimeout(60);
		try {
			xaDataSource.setLoginTimeout(60);
		} catch (SQLException e) {
		}
		xaDataSource.setMaintenanceInterval(60);
		xaDataSource.setTestQuery(validationQuery);

		return xaDataSource;
	}

	@Bean(name = "jdbc_loan")
	public NamedParameterJdbcTemplate jdbc_loan() {
		NamedParameterJdbcTemplate jdbc_loan = new NamedParameterJdbcTemplate(ds_loan());
		return jdbc_loan;
	}

	@Bean(name = "jdbcCall_loan")
	public SimpleJdbcCall jdbcCall_loan() {
		SimpleJdbcCall jdbcCall_loan = new SimpleJdbcCall(ds_loan());
		return jdbcCall_loan;
	}
}
